from .base import Object, Set
from .style import Style
from .constants import WdCollapseDirection, WdStatistic, WdMultipleWordConversionsMode
from .field import Fields
from .inline import InlineShapes

class Range(Object):
    # properties {{{1
    @property
    def Application(self):
        return self.Instance.Application

    @property
    def Bold(self):
        return self.Instance.Bold

    @property
    def BoldBi(self):
        return self.Instance.BoldBi

    @property
    def BookmarkID(self):
        return self.Instance.BookmarkID

    @property
    def Bookmarks(self):
        return self.Instance.Bookmarks

    @property
    def Borders(self):
        return self.Instance.Borders

    @property
    def Case(self):
        return self.Instance.Case

    @property
    def Cells(self):
        return self.Instance.Cells

    @property
    def Characters(self):
        return Characters(self.Instance.Characters)

    @property
    def CharacterStyle(self):
        return self.Instance.CharacterStyle

    @property
    def CharacterWidth(self):
        return self.Instance.CharacterWidth

    @property
    def Columns(self):
        return self.Instance.Columns

    @property
    def Comments(self):
        return self.Instance.Comments

    @property
    def Conflicts(self):
        return self.Instance.Conflicts

    @property
    def ContentControls(self):
        return self.Instance.ContentControls

    @property
    def Creator(self):
        return self.Instance.Creator

    @property
    def DisableCharacterSpaceGrid(self):
        return self.Instance.DisableCharacterSpaceGrid

    @property
    def Document(self):
        return self.Instance.Document

    @property
    def Duplicate(self):
        return self.Instance.Duplicate

    @property
    def Editors(self):
        return self.Instance.Editors

    @property
    def EmphasisMark(self):
        return self.Instance.EmphasisMark

    @property
    def End(self) -> int:
        return self.Instance.End

    @property
    def EndnoteOptions(self):
        return self.Instance.EndnoteOptions

    @property
    def Endnotes(self):
        return self.Instance.Endnotes

    @property
    def EnhMetaFileBits(self):
        return self.Instance.EnhMetaFileBits

    @property
    def Fields(self) -> Fields:
        return Fields(self.Instance.Fields)

    @property
    def Find(self):
        return self.Instance.Find

    @property
    def FitTextWidth(self):
        return self.Instance.FitTextWidth

    @property
    def Font(self):
        return self.Instance.Font

    @property
    def FootnoteOptions(self):
        return self.Instance.FootnoteOptions

    @property
    def Footnotes(self):
        return self.Instance.Footnotes

    @property
    def FormattedText(self):
        return self.Instance.FormattedText

    @property
    def FormFields(self):
        return self.Instance.FormFields

    @property
    def Frames(self):
        return self.Instance.Frames

    @property
    def GrammarChecked(self):
        return self.Instance.GrammarChecked

    @property
    def GrammaticalErrors(self):
        return self.Instance.GrammaticalErrors

    @property
    def HighlightColorIndex(self):
        return self.Instance.HighlightColorIndex

    @property
    def HorizontalInVertical(self):
        return self.Instance.HorizontalInVertical

    @property
    def HTMLDivisions(self):
        return self.Instance.HTMLDivisions

    @property
    def Hyperlinks(self):
        return self.Instance.Hyperlinks

    @property
    def ID(self):
        return self.Instance.ID

    @property
    def Information(self):
        return self.Instance.Information

    @property
    def InlineShapes(self) -> InlineShapes:
        return InlineShapes(self.Instance.InlineShapes)

    @property
    def IsEndOfRowMark(self):
        return self.Instance.IsEndOfRowMark

    @property
    def Italic(self):
        return self.Instance.Italic

    @property
    def ItalicBi(self):
        return self.Instance.ItalicBi

    @property
    def Kana(self):
        return self.Instance.Kana

    @property
    def LanguageDetected(self):
        return self.Instance.LanguageDetected

    @property
    def LanguageID(self):
        return self.Instance.LanguageID

    @property
    def LanguageIDFarEast(self):
        return self.Instance.LanguageIDFarEast

    @property
    def LanguageIDOther(self):
        return self.Instance.LanguageIDOther

    @property
    def ListFormat(self):
        return self.Instance.ListFormat

    @property
    def ListParagraphs(self):
        return self.Instance.ListParagraphs

    @property
    def ListStyle(self):
        return self.Instance.ListStyle

    @property
    def Locks(self):
        return self.Instance.Locks

    @property
    def NextStoryRange(self):
        return self.Instance.NextStoryRange

    @property
    def NoProofing(self):
        return self.Instance.NoProofing

    @property
    def OMaths(self):
        return self.Instance.OMaths

    @property
    def Orientation(self):
        return self.Instance.Orientation

    @property
    def PageSetup(self):
        return self.Instance.PageSetup

    @property
    def ParagraphFormat(self):
        return ParagraphFormat(self.Instance.ParagraphFormat)

    @property
    def Paragraphs(self):
        return self.Instance.Paragraphs

    @property
    def ParagraphStyle(self):
        return self.Instance.ParagraphStyle

    @property
    def Parent(self):
        return self.Instance.Parent

    @property
    def ParentContentControl(self):
        return self.Instance.ParentContentControl

    @property
    def PreviousBookmarkID(self):
        return self.Instance.PreviousBookmarkID

    @property
    def ReadabilityStatistics(self):
        return self.Instance.ReadabilityStatistics

    @property
    def Revisions(self):
        return self.Instance.Revisions

    @property
    def Rows(self):
        return self.Instance.Rows

    @property
    def Scripts(self):
        return self.Instance.Scripts

    @property
    def Sections(self):
        return self.Instance.Sections

    @property
    def Sentences(self):
        return self.Instance.Sentences

    @property
    def Shading(self):
        return self.Instance.Shading

    @property
    def ShapeRange(self):
        return self.Instance.ShapeRange

    @property
    def ShowAll(self):
        return self.Instance.ShowAll

    @property
    def SpellingChecked(self):
        return self.Instance.SpellingChecked

    @property
    def SpellingErrors(self):
        return self.Instance.SpellingErrors

    @property
    def Start(self) -> int:
        return self.Instance.Start

    @property
    def StoryLength(self):
        return self.Instance.StoryLength

    @property
    def StoryType(self):
        return self.Instance.StoryType

    @property
    def Style(self):
        return Style(self.Instance.Style)

    @property
    def Subdocuments(self):
        return self.Instance.Subdocuments

    @property
    def SynonymInfo(self):
        return self.Instance.SynonymInfo

    @property
    def Tables(self):
        return self.Instance.Tables

    @property
    def TableStyle(self):
        return self.Instance.TableStyle

    @property
    def Text(self) -> str:
        return self.Instance.Text

    @property
    def TextRetrievalMode(self):
        return self.Instance.TextRetrievalMode

    @property
    def TextVisibleOnScreen(self):
        return self.Instance.TextVisibleOnScreen

    @property
    def TopLevelTables(self):
        return self.Instance.TopLevelTables

    @property
    def TwoLinesInOne(self):
        return self.Instance.TwoLinesInOne

    @property
    def Underline(self):
        return self.Instance.Underline

    @property
    def Updates(self):
        return self.Instance.Updates

    @property
    def WordOpenXML(self):
        return self.Instance.WordOpenXML

    @property
    def Words(self):
        return self.Instance.Words

    @property
    def XML(self):
        return self.Instance.XML

    # methods {{{1
    def AutoFormat(self):
        return self.Instance.AutoFormat()

    def Calculate(self):
        return self.Instance.Calculate()

    def CheckGrammar(self):
        return self.Instance.CheckGrammar()

    def CheckSpelling(self):
        return self.Instance.CheckSpelling()

    def CheckSynonyms(self):
        return self.Instance.CheckSynonyms()

    def Collapse(self, Direction: WdCollapseDirection=WdCollapseDirection.wdCollapseStart):
        return self.Instance.Collapse()

    def ComputeStatistics(self, Statistic: WdStatistic):
        return self.Instance.ComputeStatistics(Statistic)

    def ConvertHangulAndHanja(self, *args, **kwargs):
        """ 将指定区域的朝鲜文字转换为朝鲜文汉字，或进行相反的转换。

        参数
        名称	                必需/可选	数据类型	说明
        ConversionsMode	        可选	    Variant	    设置朝鲜文字和朝鲜文汉字之间的转换方向。 可以是下列 WdMultipleWordConversionsMode 常量之一 ：wdHangulToHanja 或 wdHanjaToHangul。 默认值是 MultipleWordConversionsMode 属性的当前值。
        FastConversion	        可选	    Variant	    如此 如果 Microsoft Word 会自动将带有转换仅输入一个建议的单词。 默认值是 HangulHanjaFastConversion 属性的当前值。
        CheckHangulEnding	    可选	    Variant	    如此 如果 Word 自动检测朝鲜文字结尾，并忽略它们。 默认值是 CheckHangulEndings 属性的当前值。 如果将 ConversionsMode 参数设置为 wdHanjaToHangul ，则忽略此参数。
        EnableRecentOrdering	可选	    Variant	    如此 如果 Word 显示最近使用过的单词建议列表的顶部。 默认值是 EnableHangulHanjaRecentOrdering 属性的当前值。
        CustomDictionary	    可选	    Variant	    自定义朝鲜文字/朝鲜文汉字转换词典的名称。 使用该参数的目的是使用主词典中所没有的朝鲜文字/朝鲜文汉字自定义转换词典。
        """
        if len(args) > 0:
            kwargs['ConversionsMode'] = args[0]
        if len(args) > 1:
            kwargs['FastConversion'] = args[1]
        if len(args) > 2:
            kwargs['CheckHangulEnding'] = args[2]
        if len(args) > 3:
            kwargs['EnableRecentOrdering'] = args[3]
        if len(args) > 4:
            kwargs['CustomDictionary'] = args[4]
        return self.Instance.ConvertHangulAndHanja(**kwargs)

    def ConvertToTable(self, *args, **kwargs):
        """ 将范围内的文本转换为表格。 以 Table 对象 返回表格 。

            语法
            ====
            expression。 ConvertToTable( _Separator_ , _NumRows_ , _NumColumns_ , _InitialColumnWidth_ , _Format_ , _ApplyBorders_ , _ApplyShading_ , _ApplyFont_ , _ApplyColor_ , _ApplyHeadingRows_ , _ApplyLastRow_ , _ApplyFirstColumn_ , _ApplyLastColumn_ , _AutoFit_ , _AutoFitBehavior_ , _DefaultTableBehavior_ )
            expression 一个表示 Range 对象的变量。
            参数
            ====
            名称	必需/可选	数据类型	说明
            Separator	可选	Variant	指定用于将文本分隔成单元格的字符。 可以是字符或下列 WdTableFieldSeparator 常量之一。 如果省略此参数，则使用 DefaultTableSeparator 属性的值。
            NumRows	可选	Variant	表格中的行数。 如果省略此参数，Microsoft Word 将根据该范围的内容设置行数。
            NumColumns	可选	Variant	表格中的列数。 如果省略此参数，Word 将根据该范围的内容设置列数。
            InitialColumnWidth	可选	Variant	每一列的初始宽度，以磅为单位。 如果省略此参数，Word 将计算并调整列宽，以使表格填满页面。
            Format	可选	Variant	指定 表格自动套用格式 对话框中列出的预定义格式之一。 可以是 WdTableFormat 常量之一。
            ApplyBorders	可选	Variant	则 应用指定格式的边框属性。
            ApplyShading	可选	Variant	则 应用指定格式的底纹属性。
            ApplyFont	可选	Variant	则 应用指定格式的字体属性。
            ApplyColor	可选	Variant	则 应用指定格式的颜色属性。
            ApplyHeadingRows	可选	Variant	则 应用指定格式的标题行的属性。
            ApplyLastRow	可选	Variant	则 应用指定格式的最后一行的属性。
            ApplyFirstColumn	可选	Variant	则 应用指定格式的第一列的属性。
            ApplyLastColumn	可选	Variant	则 应用指定格式的最后一列的属性。
            AutoFit	可选	Variant	真 要减少尽最大可能的表格列的宽度，而无需更改文字换行的单元格中。
            AutoFitBehavior	可选	Variant	设置 Word 调整表格的大小的自动调整规则。 可以是下列 WdAutoFitBehavior 常量之一。 如果 DefaultTableBehavior 是 wdWord8TableBehavior ，则忽略此参数。
            DefaultTableBehavior	可选	Variant	设置一个值，指定是否 Microsoft Word 会自动调整大小以适合内容 (自动调整) 表中的单元格。 可以是一个 WdDefaultTableBehavior 常量。
        """
        return self.Instance.ConvertToTable(**kwargs)

    def Copy(self):
        return self.Instance.Copy()

    def CopyAsPicture(self):
        return self.Instance.CopyAsPicture()

    def Cut(self):
        return self.Instance.Cut()

    def Delete(self):
        return self.Instance.Delete()

    def DetectLanguage(self):
        return self.Instance.DetectLanguage()

    def EndOf(self):
        return self.Instance.EndOf()

    def Expand(self):
        return self.Instance.Expand()

    def ExportAsFixedFormat(self):
        return self.Instance.ExportAsFixedFormat()

    def ExportAsFixedFormat2(self):
        return self.Instance.ExportAsFixedFormat2()

    def ExportFragment(self):
        return self.Instance.ExportFragment()

    def GetSpellingSuggestions(self):
        return self.Instance.GetSpellingSuggestions()

    def GoTo(self):
        return self.Instance.GoTo()

    def GoToEditableRange(self):
        return self.Instance.GoToEditableRange()

    def GoToNext(self):
        return self.Instance.GoToNext()

    def GoToPrevious(self):
        return self.Instance.GoToPrevious()

    def ImportFragment(self):
        return self.Instance.ImportFragment()

    def InRange(self):
        return self.Instance.InRange()

    def InsertAfter(self, Text:str):
        return self.Instance.InsertAfter(Text)

    def InsertAlignmentTab(self):
        return self.Instance.InsertAlignmentTab()

    def InsertAutoText(self):
        return self.Instance.InsertAutoText()

    def InsertBefore(self):
        return self.Instance.InsertBefore()

    def InsertBreak(self):
        return self.Instance.InsertBreak()

    def InsertCaption(self):
        return self.Instance.InsertCaption()

    def InsertCrossReference(self):
        return self.Instance.InsertCrossReference()

    def InsertDatabase(self):
        return self.Instance.InsertDatabase()

    def InsertDateTime(self):
        return self.Instance.InsertDateTime()

    def InsertFile(self):
        return self.Instance.InsertFile()

    def InsertParagraph(self):
        return self.Instance.InsertParagraph()

    def InsertParagraphAfter(self):
        return self.Instance.InsertParagraphAfter()

    def InsertParagraphBefore(self):
        return self.Instance.InsertParagraphBefore()

    def InsertSymbol(self):
        return self.Instance.InsertSymbol()

    def InsertXML(self):
        return self.Instance.InsertXML()

    def InStory(self):
        return self.Instance.InStory()

    def IsEqual(self):
        return self.Instance.IsEqual()

    def LookupNameProperties(self):
        return self.Instance.LookupNameProperties()

    def ModifyEnclosure(self):
        return self.Instance.ModifyEnclosure()

    def Move(self):
        return self.Instance.Move()

    def MoveEnd(self):
        return self.Instance.MoveEnd()

    def MoveEndUntil(self):
        return self.Instance.MoveEndUntil()

    def MoveEndWhile(self):
        return self.Instance.MoveEndWhile()

    def MoveStart(self):
        return self.Instance.MoveStart()

    def MoveStartUntil(self):
        return self.Instance.MoveStartUntil()

    def MoveStartWhile(self):
        return self.Instance.MoveStartWhile()

    def MoveUntil(self):
        return self.Instance.MoveUntil()

    def MoveWhile(self):
        return self.Instance.MoveWhile()

    def Next(self):
        return self.Instance.Next()

    def NextSubdocument(self):
        return self.Instance.NextSubdocument()

    def Paste(self):
        return self.Instance.Paste()

    def PasteAndFormat(self):
        return self.Instance.PasteAndFormat()

    def PasteAppendTable(self):
        return self.Instance.PasteAppendTable()

    def PasteAsNestedTable(self):
        return self.Instance.PasteAsNestedTable()

    def PasteExcelTable(self):
        return self.Instance.PasteExcelTable()

    def PasteSpecial(self):
        return self.Instance.PasteSpecial()

    def PhoneticGuide(self):
        return self.Instance.PhoneticGuide()

    def Previous(self):
        return self.Instance.Previous()

    def PreviousSubdocument(self):
        return self.Instance.PreviousSubdocument()

    def Relocate(self):
        return self.Instance.Relocate()

    def Select(self):
        return self.Instance.Select()

    def SetListLevel(self):
        return self.Instance.SetListLevel()

    def SetRange(self):
        return self.Instance.SetRange()

    def Sort(self):
        return self.Instance.Sort()

    def SortAscending(self):
        return self.Instance.SortAscending()

    def SortByHeadings(self):
        return self.Instance.SortByHeadings()

    def SortDescending(self):
        return self.Instance.SortDescending()

    def StartOf(self):
        return self.Instance.StartOf()

    def TCSCConverter(self):
        return self.Instance.TCSCConverter()

    def WholeStory(self):
        return self.Instance.WholeStory()

    def saveobj(self):
        data = {
            'Class': 'Range',
            'Start': self.Start,
            'End': self.End,
            'Text': self.Text
        }
        if self.InlineShapes.Count > 0:
            data['InlineShapes'] = self.InlineShapes.saveobj()
        if self.Fields.Count > 0:
            data['Fields'] = self.Fields.saveobj()
        return data


class Characters(Object):
    def __init__(self, instance):
        super().__init__(instance, elementType=Range)

